package com.andova.image

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.andova.ext.i
import com.andova.libyuv.LibYUV
import org.junit.Test
import org.junit.runner.RunWith
import java.nio.ByteBuffer

@RunWith(AndroidJUnit4::class)
class GlLibYUVTest {
    companion object {
        const val BENCHMARK_WIDTH = 4
        const val BENCHMARK_HEIGHT = 3
    }

    @Test
    fun testSHL() {
        val a = 11 shl 8
        val b = 12
        val c = (a + b)
        val d = c shr 8
        println("$a,$c,$d")
    }

    @Test
    fun testNativeI422ToNV21() {
        for (c in 0..Int.MAX_VALUE) {
            val y = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) // 4:3
            val u = byteArrayOf(21, 22, 23, 24, 25)
            val v = byteArrayOf(31, 32, 33, 34, 35)
            val ybuf = ByteBuffer.allocateDirect(y.size).put(y)
            val ubuf = ByteBuffer.allocateDirect(u.size).put(u)
            val vbuf = ByteBuffer.allocateDirect(v.size).put(v)
            val yuv = ByteArray(4 * 3 * 3 / 2)
            LibYUV.YUV422ToNV21(ybuf, ubuf, vbuf, yuv, 0, 4, 3)
            val sb = StringBuilder()
            sb.append('[')
            for (i in yuv) {
                sb.append(i)
                sb.append(',')
            }
            sb.delete(sb.length - 1, sb.length)
            sb.append(']')
            i(sb.toString())
        }
        Thread.sleep(500000L)
    }

    @Suppress("LocalVariableName")
    @Test
    fun testAndroid420ToI420() {
        val src_y = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) // 4:3
        val src_u = byteArrayOf(21, 22, 23)
        val src_v = byteArrayOf(31, 32, 33)
        val dst_y = ByteArray(src_y.size)
        val dst_u = ByteArray(src_u.size)
        val dst_v = ByteArray(src_v.size)
        LibYUV.TestAndroid420ToI420(src_y, src_u, src_v, dst_y, dst_u, dst_v, 4, 3)
        val sb = StringBuilder()
        sb.append("dst_y: [")
        for (i in dst_y) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_u: [")
        for (i in dst_u) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_v: [")
        for (i in dst_v) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)
    }

    @Suppress("LocalVariableName")
    @Test
    fun testI422ToI420() {
        val src_y = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) // 4:3
        val src_u = byteArrayOf(21, 22, 23, 24, 25)
        val src_v = byteArrayOf(31, 32, 33, 34, 35)
        val dst_y = ByteArray(src_y.size)
        val dst_u = ByteArray((src_u.size + 1) / 2)
        val dst_v = ByteArray((src_v.size + 1) / 2)
        LibYUV.TestI422ToI420(src_y, src_u, src_v, dst_y, dst_u, dst_v, 4, 3)
        val sb = StringBuilder()
        sb.append("dst_y: [")
        for (i in dst_y) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_u: [")
        for (i in dst_u) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_v: [")
        for (i in dst_v) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)
    }

    @Suppress("LocalVariableName")
    @Test
    fun testI444ToI420() {
        val src_y = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) // 4:3
        val src_u = byteArrayOf(21, 22, 23, 24, 25, 26, 27, 28, 29, 40, 41, 42)
        val src_v = byteArrayOf(31, 32, 33, 34, 35, 36, 37, 38, 39, 50, 51, 52)
        val dst_y = ByteArray(src_y.size)
        val dst_u = ByteArray(BENCHMARK_WIDTH)
        val dst_v = ByteArray(BENCHMARK_WIDTH)
        LibYUV.TestI444ToI420(src_y, src_u, src_v, dst_y, dst_u, dst_v, BENCHMARK_WIDTH, BENCHMARK_HEIGHT)
        val sb = StringBuilder()
        sb.append("dst_y: [")
        for (i in dst_y) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_u: [")
        for (i in dst_u) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_v: [")
        for (i in dst_v) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)
    }

    @Test
    fun testI420ToNV21() {
        val y = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) // 4:3
        val u = byteArrayOf(21, 22, 23, 24, 25)
        val v = byteArrayOf(31, 32, 33, 34, 35)
        val yuv = ByteArray(4 * 3 * 3 / 2)
        LibYUV.TestI420ToNV21(y, u, v, yuv, 4, 3)
        val sb = StringBuilder()
        sb.append('[')
        for (i in yuv) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)
    }

    @Suppress("LocalVariableName")
    @Test
    fun testNV21ToI420() {
        val src_yuv = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 31, 21, 32, 22, 33, 23) // 4:3
        val dst_y = ByteArray(src_yuv.size * 2 / 3)
        val dst_u = ByteArray(dst_y.size / 4)
        val dst_v = ByteArray(dst_y.size / 4)
        LibYUV.TestNV21ToI420(src_yuv, dst_y, dst_u, dst_v, 4, 3)
        val sb = StringBuilder()
        sb.append("dst_y: [")
        for (i in dst_y) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_u: [")
        for (i in dst_u) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)

        sb.clear()
        sb.append("dst_v: [")
        for (i in dst_v) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)
    }

    @Suppress("LocalVariableName")
    @Test
    fun testHalfMergeUVPlane() {
        val src_u = byteArrayOf(21, 22, 23, 24, 25) // 4:3
        val src_v = byteArrayOf(31, 32, 33, 34, 35) // 4:3
        val dst_uv = ByteArray(BENCHMARK_WIDTH * BENCHMARK_HEIGHT / 2)
        LibYUV.TestHalfMergeUVPlane(src_u, src_v, dst_uv, BENCHMARK_WIDTH, BENCHMARK_HEIGHT)
        val sb = StringBuilder()
        sb.append("dst_uv: [")
        for (i in dst_uv) {
            sb.append(i)
            sb.append(',')
        }
        sb.delete(sb.length - 1, sb.length)
        sb.append(']')
        println(sb)
    }
}